//
//  BERegularExpressionExtension.swift
//  BasicExtensions
//
//  Created by JY_NEW on 2022/1/8.
//

import Foundation

extension NSTextCheckingResult {
    ///从正则结果获取字符串
    public func string(for text: String) -> String {
        return text.middle(self.range)
    }
    ///从正则结果获取字符串
    public func string(for text: String, at group: Int) -> String {
        return text.middle(self.range(at: group))
    }
    ///从正则结果获取字符串
    @available(iOS 11.0, *)
    public func string(for text: String, at group: String) -> String {
        return text.middle(self.range(withName: group))
    }
}

extension String {
    ///根据正则查找字符串
    public func enumerateMatches(_ pattern: String, options: NSRegularExpression.Options = [], matchingOptions: NSRegularExpression.MatchingOptions = [], using block:(NSTextCheckingResult) -> Void) {
        let reg = try? NSRegularExpression(pattern: pattern, options: options)
        reg?.enumerateMatches(in: self, options: matchingOptions, range: self.nsRange, using: { result, _, _ in
            if let result = result {
                block(result)
            }
        })
    }
    ///根据正则替换字符串
    public func byReplacingMatches(_ pattern: String, options: NSRegularExpression.Options = [], matchingOptions: NSRegularExpression.MatchingOptions = [], to template: String) -> String {
        let reg = try? NSRegularExpression(pattern: pattern, options: options)
        return reg?.stringByReplacingMatches(in: self, options: matchingOptions, range: self.nsRange, withTemplate: template) ?? self
    }
    ///根据正则替换字符串, block返回nil代表不替换，若要替换为空则返回空字符串
    public func byReplacingMatches(_ pattern: String, options: NSRegularExpression.Options = [], matchingOptions: NSRegularExpression.MatchingOptions = [], using block:(NSTextCheckingResult) -> String?) -> String {
        let string = NSMutableString(string: self)
        var offset = 0
        self.enumerateMatches(pattern, options: options, matchingOptions: matchingOptions) { result in
            if let template = block(result) {
                string.replaceCharacters(in: result.range.byOffset(offset), with: template)
                offset += template.count - result.range.length
            }
        }
        return string as String
    }
}

extension NSMutableAttributedString {
    ///根据正则替换字符串, block返回nil代表不替换，若要替换为空则返回空字符串
    public func replacingMatches(_ pattern: String, options: NSRegularExpression.Options = [], matchingOptions: NSRegularExpression.MatchingOptions = [], using block:(NSTextCheckingResult) -> NSAttributedString?) {
        var offset = 0
        self.string.enumerateMatches(pattern, options: options, matchingOptions: matchingOptions) { result in
            if let template = block(result) {
                self.replaceCharacters(in: result.range.byOffset(offset), with: template)
                offset += template.length - result.range.length
            }
        }
    }
    ///根据正则替换字符串
    public func replacingMatches(_ pattern: String, options: NSRegularExpression.Options = [], matchingOptions: NSRegularExpression.MatchingOptions = [], to template: NSAttributedString) {
        self.replacingMatches(pattern, options: options, matchingOptions: matchingOptions, using: { _ in template })
    }
    ///根据正则添加样式
    public func addAttributes(_ attrs: [NSAttributedString.Key: Any], pattern: String, options: NSRegularExpression.Options = [], matchingOptions: NSRegularExpression.MatchingOptions = [], at group: Int = 0) {
        self.string.enumerateMatches(pattern, options: options, matchingOptions: matchingOptions) { result in
            self.addAttributes(attrs, range: result.range(at: group))
        }
    }
    ///根据正则添加样式
    public func addAttributes(_ attrs: [NSAttributedString.Key: Any], pattern: String, options: NSRegularExpression.Options = [], matchingOptions: NSRegularExpression.MatchingOptions = [], replacing: (NSTextCheckingResult) -> String?) {
        var offset = 0
        self.string.enumerateMatches(pattern, options: options, matchingOptions: matchingOptions) { result in
            let range = result.range.byOffset(offset)
            if let template = replacing(result) {
                self.replaceCharacters(in: range, with: template)
                self.addAttributes(attrs, range: NSMakeRange(range.location, template.count))
                offset += template.count - result.range.length
            }else{
                self.addAttributes(attrs, range: range)
            }
        }
    }
    ///根据正则添加样式
    public func addAttributes(_ attrs: [NSAttributedString.Key: Any], pattern: String, options: NSRegularExpression.Options = [], matchingOptions: NSRegularExpression.MatchingOptions = [], replacing group: Int) {
        let text = self.string
        self.addAttributes(attrs, pattern: pattern, options: options, matchingOptions: matchingOptions, replacing: { result in
            return result.string(for: text, at: group)
        })
    }
    ///根据正则添加样式
    public func addAttributes(_ name: NSAttributedString.Key, value: Any, pattern: String, options: NSRegularExpression.Options = [], matchingOptions: NSRegularExpression.MatchingOptions = [], at group: Int = 0) {
        self.addAttributes([name: value], pattern: pattern, options: options, matchingOptions: matchingOptions, at: group)
    }
    ///根据正则添加样式
    public func addAttributes(_ name: NSAttributedString.Key, value: Any, pattern: String, options: NSRegularExpression.Options = [], matchingOptions: NSRegularExpression.MatchingOptions = [], replacing: (NSTextCheckingResult) -> String?) {
        self.addAttributes([name: value], pattern: pattern, options: options, matchingOptions: matchingOptions, replacing: replacing)
    }
    ///根据正则添加样式
    public func addAttributes(_ name: NSAttributedString.Key, value: Any, pattern: String, options: NSRegularExpression.Options = [], matchingOptions: NSRegularExpression.MatchingOptions = [], replacing group: Int) {
        self.addAttributes([name: value], pattern: pattern, options: options, matchingOptions: matchingOptions, replacing: group)
    }
}
